package com.zmn.oms.dubbo.impl.callcenter;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.oms.business.interfaces.work.distribute.DistributeTimeoutBservice;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.dto.CallResultDTO;
import com.zmn.oms.dubbo.interfaces.callcenter.CallBackRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.dto.remark.OrderRemarkDetailDTO;
import com.zmn.oms.model.dto.timeout.DistributeTimeoutDTO;
import com.zmn.oms.model.dto.work.modify.must.ZsCancelDTO;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.normal.business.interfaces.work.ZsNormalWorkBService;
import com.zmn.track.common.constant.TrackConfigConsts;
import com.zmn.track.common.constant.apply.cancel.CancelApplyConsts;
import com.zmn.track.dubbo.dio.apply.cancel.CheckAllowApplyCancelDIO;
import com.zmn.track.dubbo.dio.apply.cancel.SubmitApplyCancelDIO;
import com.zmn.track.dubbo.dro.apply.cancel.CheckAllowApplyCancelDRO;
import com.zmn.track.dubbo.interfaces.apply.cancel.OrderCancelApplyListRemoteService;
import com.zmn.track.dubbo.interfaces.apply.cancel.OrderCancelApplyModifyRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;
import java.util.Objects;


/**
 * 类描述：外呼结果
 *
 * @author ligang
 * @since 2021/10/19 17:26
 */
@Service(loadbalance = "roundrobin", timeout = 5000, retries = 2, version = DubboConsts.INTERFACE_VERSION, validation = "true")
@Slf4j
public class CallBackRemoteServiceImpl implements CallBackRemoteService {

    @Reference(version = com.zmn.track.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    private OrderCancelApplyListRemoteService orderCancelApplyListRemoteService;
    @Reference(version = com.zmn.track.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    private OrderCancelApplyModifyRemoteService orderCancelApplyModifyRemoteService;

    @Autowired
    protected ZsNormalWorkBService zsNormalWorkBService;
    @Autowired
    protected OrderWorkService orderWorkService;
    @Autowired
    private DistributeTimeoutBservice distributeTimeoutBservice;

    @NacosValue(value = "${call.order.remind.useNewRemind:false}", autoRefreshed = true)
    private Boolean useNewRemind = false;

    /**
     * 派单超时外呼回传
     */
    @Override
    public ResponseDTO modifyDistributeTimeoutCallResult(String data, String sign) {
        log.info("派单超时外呼回调接口入参[{}]-[{}]", data, sign);
        if (useNewRemind) {
            log.info("#CallBackRemoteServiceImpl#modifyDistributeTimeoutCallResult 使用新remind外呼");
            return ResponseDTO.success();
        }
        CallResultDTO callResultDTO = JSONObject.parseObject(data, CallResultDTO.class);
        // 成功处理
        if (!Objects.equals(callResultDTO.getCallStatus(), GlobalConsts.YES) ||
                StringUtil.isBlank(callResultDTO.getUserKeys())) {
            return ResponseDTO.fail("用户操作不能为空");
        }
        if (StringUtil.isBlank(callResultDTO.getBizId())) {
            return ResponseDTO.fail("业务唯一编号不能为空");
        }
        Long workId = Long.valueOf(callResultDTO.getBizId());
        Long orderId = workId;
        String[] userKeyArr = callResultDTO.getUserKeys().split(";");

        // 查询工单信息
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(workId, workId);

        // 用户输入等待
        if (Objects.equals(userKeyArr[0], String.valueOf(GlobalConsts.YES))) {
            DistributeTimeoutDTO distributeTimeoutDTO = new DistributeTimeoutDTO();
            distributeTimeoutDTO.setOrderId(orderId);
            distributeTimeoutDTO.setWorkId(workId);
            distributeTimeoutDTO.setReasonId(TrackConfigConsts.TRACK_REASON_ID_USER_WAIT);
            distributeTimeoutDTO.setOperator(orderWork.getUserId() == null ? "" : orderWork.getUserId().toString());
            distributeTimeoutDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_USER);
            distributeTimeoutDTO.setOperatorId(orderWork.getUserId());
            distributeTimeoutDTO.setOperatorLogRemark("用户电话按键继续等待");
            log.info("派单超时，用户按键继续等待，发起跟单[{}]", workId);
            distributeTimeoutBservice.timeoutProcess(distributeTimeoutDTO);
            return ResponseDTO.success();
        }

        // 用户选择取消订单
        if (Objects.equals(userKeyArr[0], String.valueOf(GlobalConsts.NO))) {
            try {
                // 是否真实取消
                boolean isRealCancel = true;

                // 判断是否允许申请
                CheckAllowApplyCancelDIO applyCancelDIO = CheckAllowApplyCancelDIO
                        .builder()
                        .orderId(orderId)
                        .workId(workId)
                        .applySource(CancelApplyConsts.CANCEL_APPLY_SOURCE_PHONE_KEYS)
                        .channelId(orderWork.getChannelId())
                        .cityId(orderWork.getCityId())
                        .channelId(orderWork.getChannelId())
                        .servCategId(orderWork.getServCategId())
                        .showCategId(orderWork.getShowCategId())
                        .build();
                log.info("{} 检查是否允许申请取消入参 applyCancelDIO={}", workId, applyCancelDIO);
                ResponseDTO<CheckAllowApplyCancelDRO> checkAllowApplyCancelDROResponseDTO = orderCancelApplyListRemoteService.checkAllowApplyCancel(applyCancelDIO);
                log.info("{} 检查是否允许申请取消出参 checkAllowApplyCancelDROResponseDTO={}", workId, checkAllowApplyCancelDROResponseDTO);
                if (!checkAllowApplyCancelDROResponseDTO.isSuccess() || Objects.isNull(checkAllowApplyCancelDROResponseDTO.getData())) {
                    isRealCancel = false;
                }
                CheckAllowApplyCancelDRO dro = checkAllowApplyCancelDROResponseDTO.getData();
                if (dro.isAllowApply()) {
                    isRealCancel = false;
                }

                if (isRealCancel) {
                    // 真实取消
                    ZsCancelDTO zsCancelDTO = new ZsCancelDTO();
                    zsCancelDTO.setOrderId(workId);
                    zsCancelDTO.setWorkId(workId);
                    List<OrderRemarkDetailDTO> detailDTOList = Lists.newArrayList();
                    OrderRemarkDetailDTO dto = new OrderRemarkDetailDTO();
                    dto.setMapId(OrderConsts.DISTRIBUTE_TIMEOUT_WAIT_ID);
                    dto.setMapName("派单超时用户取消");
                    detailDTOList.add(dto);
                    zsCancelDTO.setDetailDTOList(detailDTOList);

                    // 操作人信息
                    zsCancelDTO.setOperator(orderWork.getUserId() == null ? "" : orderWork.getUserId().toString());
                    zsCancelDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_USER);
                    zsCancelDTO.setOperatorId(orderWork.getUserId());
                    zsCancelDTO.setEntranceId(91);
                    zsCancelDTO.setOperatorLogRemark("用户电话按键选择取消");

                    log.info("派单超时，用户按键取消订单[{}] 入参：{}", workId, JSON.toJSONString(zsCancelDTO));
                    zsNormalWorkBService.saveCancel(zsCancelDTO);
                    return ResponseDTO.success();
                }else {
                    // 发起取消申请
                    Map<Integer, String> reasonMap = Maps.newHashMap();
                    reasonMap.put(OrderConsts.DISTRIBUTE_TIMEOUT_WAIT_ID, "派单超时用户取消");
                    SubmitApplyCancelDIO submitApplyCancelDIO = SubmitApplyCancelDIO
                            .builder()
                            .orderId(orderId)
                            .workId(workId)
                            .applySource(CancelApplyConsts.CANCEL_APPLY_SOURCE_PHONE_KEYS)
                            .operator(orderWork.getCreater())
                            .operatorId(orderWork.getUserId())
                            .operatorType(GlobalConsts.OPERATE_USER_TYPE_USER)
                            .reasonMap(reasonMap)
                            .build();
                    log.info("{} 提交取消申请#submitApplyCancel submitApplyCancelDIO={}", workId, submitApplyCancelDIO);
                    ResponseDTO responseDTO = orderCancelApplyModifyRemoteService.submitApplyCancel(submitApplyCancelDIO);
                    log.info("{} 提交取消申请#submitApplyCancel responseDTO={}", workId, responseDTO);
                    return responseDTO;
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("orderId={} 派单超时外呼回调取消订单失败:{}", orderId, e);
                return ResponseDTO.fail(e.getMessage());
            }
        }
        return ResponseDTO.success();
    }
}
